package com.hzjh.base.http

import com.hzjh.base.log.JHLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.util.concurrent.TimeoutException

class Request<T> {

    private var request: (suspend () -> BaseResponse<T>)? = null

    private var response: ((BaseResponse<T>?) -> Unit)? = null

    var originResponse: ((String?) -> Unit)? = null

    private var start: (() -> Unit)? = null
    var realStart: (() -> Unit)? = null

    var success: ((T) -> Unit)? = null

    var realSuccess: ((String) -> Unit)? = null

    var error: ((String) -> Unit)? = null

    var originError:((String)->Unit)?=null

    private var complete: (() -> Unit)? = null
    var realComplete: (() -> Unit)? = null

    fun onStart(start: () -> Unit) {
        this.start = start
    }
    fun onRealStart(start: () -> Unit) {
        this.realStart = start
    }

    fun onRequest(request: suspend () -> BaseResponse<T>) {
        this.request = request
    }

    fun onSuccess(success: (T) -> Unit) {
        this.success = success
    }

    fun onRealSuccess(success: ((String) -> Unit)?) {
        this.realSuccess = success
    }

    fun onError(error: (String) -> Unit) {
        this.error = error
    }

    fun onRealError(error: (String) -> Unit) {
        this.originError = error
    }

    fun onResponse(response: (BaseResponse<T>?) -> Unit) {
        this.response = response
    }

    fun onRealResponse(response: (String?) -> Unit) {
        this.originResponse = response
    }

    fun onComplete(complete: () -> Unit) {
        this.complete = complete
    }
    fun onRealComplete(complete: () -> Unit) {
        this.realComplete = complete
    }

    fun toRequest(viewModelScope: CoroutineScope) {
        viewModelScope.launch(context = Dispatchers.Main) {
            start?.invoke()
            try {
                val realResponse = withContext(Dispatchers.IO) {
                    request?.invoke()
                }
                response?.invoke(realResponse)
            } catch (e: Exception) {
                JHLogger.e("OkHttpClient",e.message?:"")
                when (e) {
                    is IllegalStateException -> {
                        val errorMsg="Not a JSON Object: "
                        var message = e.message ?: ""
                        if(message.startsWith(errorMsg)){
                            message = message.substring(errorMsg.length)
                            originResponse?.invoke(message)
                        }else {
                            error?.invoke(e.message!!)
                        }
                    }
                    is UnknownHostException -> error?.invoke(e.message!!)
                    is TimeoutException -> error?.invoke(e.message!!)
                    is SocketTimeoutException -> error?.invoke(e.message!!)
                    else -> error?.invoke(e.message!!)
                }
            } finally {
                complete?.invoke()
            }
        }
    }
}
